package com.gxa.jd.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.gxa.exception.CustomerException;
import com.gxa.exception.MessageCode;
import com.gxa.jd.config.RedisKey;
import com.gxa.jd.mapper.UserMapper;
import com.gxa.jd.pojo.User;
import com.gxa.jd.service.UserService;
import com.gxa.entity.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;


    @Autowired
    private RedisTemplate redisTemplate;


    @Autowired
    private RestTemplate restTemplate;


    public static final String LOGIN="sfvasfewsjkfbacvasjcasjcj";

    private static final String REQUEST_URL = "https://api.weixin.qq.com/sns/jscode2session";



    //微信授权登录
    @Override
    public Map<String, String> wxLogin( String code) throws CustomerException {

        Map<String,String> result=new HashMap<>();

        //配置前端给的appId和secret 不要配置我的!!!
        String appId = "wx60235935832f5087";
        String secret = "d27626e574dd9280cbc2c63341b26566";


        String url = "https://api.weixin.qq.com/sns/jscode2session?appid="+appId
                + "&secret=" + secret
                + "&js_code=" + code
                + "&grant_type=authorization_code";

        String jsonData = this.restTemplate.getForObject(url, String.class);

        log.info("微信登录的数据为:{}",jsonData);

        if (jsonData.contains( "errcode")) {
            log.info("微信授权失败!");
            result.put("msg", "微信授权失败");
            return result;
        }


        JSONObject jsonObject = JSONObject.parseObject(jsonData);

        String openId=jsonObject.getString("openid");
        String session_key=jsonObject.getString("sessionKey");

        log.info("openid:{}",openId);


        User record=new User();
        record.setOpenId(openId);
        User user = userMapper.selectOne(record);
        if(user==null){
            //匿名注册
            log.info("匿名绑定微信账户:{}",openId);
            user=new User();
            //用户名也可以让前端获取传过来，根据具体情况修改
            user.setUsername("用户:"+openId);
            user.setStatus(1);//正常账号
            user.setOpenId(openId);
            userMapper.insert(user);
        }

        if(!StringUtils.isEmpty(user.getToken())){
            //获取上次的token,获取后移除上一次的登录信息
            redisTemplate.delete(LOGIN+user.getToken());
        }

        //生成token，存储登录信息
        String token= UUID.randomUUID().toString().replace("-","");
        //更新ip和登录时间
        user.setToken(token);
        user.setLastLoginTime(new Date());
        userMapper.updateByPrimaryKey(user);

        user.setSessionKey(session_key);

        redisTemplate.boundValueOps(LOGIN+token).set(user);
        //时间自己根据具体情况配置
        redisTemplate.boundValueOps(LOGIN+token).expire(60*60*120, TimeUnit.SECONDS);


        result.put("token",token);
        return result;
    }




    //短信一键登录
    @Override
    public Map<String, String> login(String phone, String code) throws CustomerException {

        //一键登录

        //1.获取服务器存储的验证码
        String serverCode= (String) redisTemplate.boundValueOps(RedisKey.LOGIN_SMS +phone).get();

        if(StringUtils.isEmpty(serverCode)){
            //验证码失效
            throw  new CustomerException(MessageCode.LOGIN_SMS_EXPIRE);
        }
        if(!code.equals(serverCode)){
            //验证码输入错误
            throw  new CustomerException(MessageCode.LOGIN_SMS_ERROR);
        }

        User record=new User();
        record.setPassword(phone);
        User user = userMapper.selectOne(record);
        if(user==null){
            //匿名注册
            System.out.println("用户没有账号，匿名注册:"+phone);
            user=new User();
            user.setPhone(phone);
            user.setUsername("用户:"+phone);
            user.setStatus(1);//正常账号

            userMapper.insert(user);

        }

        if(user.getStatus()!=1){
            throw new CustomerException(MessageCode.USER_NO);
        }

        //我怎么知道他是手机端?

        //获取上次的token,获取后移除上一次的登录信息
        if(!StringUtils.isEmpty(user.getToken())){
            redisTemplate.delete(LOGIN+user.getToken());
        }

        //生成token，存储登录信息
        String token=UUID.randomUUID().toString().replace("-","");

        //处理登录

        // 设置ip  去掉了


        user.setLastLoginTime(new Date());
        user.setToken(token);
        userMapper.insertSelective(user);//更新ip和登录时间


        redisTemplate.boundValueOps(LOGIN+token).set(user);
        redisTemplate.boundValueOps(LOGIN+token).expire(60*60*2, TimeUnit.SECONDS);

        Map<String,String> result=new HashMap<>();
        result.put("token",token);

        return result;
    }




    @Override
    public User queryUserByToken(String token) throws CustomerException {

        User user = (User) redisTemplate.boundValueOps(LOGIN + token).get();
        if (ObjectUtils.isEmpty(user)) {
            System.out.println("无效token");
            throw new CustomerException(MessageCode.TOKEN_NO);
        }

        //要更新失效时间
        redisTemplate.boundValueOps(LOGIN+token).expire(60*60*48, TimeUnit.SECONDS);

        return user;
    }


    @Override
    public void updateUser(User user) {
        //不要用redis里面查询出的用户信息，重新获取数据库的用户信息，只设置电话 以免修改到其他信息

        User record=new User();
        record.setUsername(user.getUsername());
        User dataUser = userMapper.selectOne(record);
        dataUser.setPhone(user.getPhone());
        userMapper.updateByPrimaryKey(dataUser);
    }


    /**
     * 返回全部记录
     *
     * @return
     */
    @Override
    public List<User> findAll() {
        return userMapper.selectAll();
    }

    /**
     * 分页查询
     *
     * @param page 页码
     * @param size 每页记录数
     * @return 分页结果
     */
    @Override
    public PageResult<User> findPage(int page, int size) {
        PageHelper.startPage(page, size);
        Page<User> users = (Page<User>) userMapper.selectAll();
        return new PageResult<User>(users.getTotal(), users.getResult());
    }

    /**
     * 条件查询
     *
     * @param searchMap 查询条件
     * @return
     */
    @Override
    public List<User> findList(Map<String, Object> searchMap) {
        Example example = createExample(searchMap);
        return userMapper.selectByExample(example);
    }

    /**
     * 分页+条件查询
     *
     * @param searchMap
     * @param page
     * @param size
     * @return
     */
    @Override
    public PageResult<User> findPage(Map<String, Object> searchMap, int page, int size) {
        PageHelper.startPage(page, size);
        Example example = createExample(searchMap);
        Page<User> users = (Page<User>) userMapper.selectByExample(example);
        return new PageResult<User>(users.getTotal(), users.getResult());
    }

    /**
     * 根据Id查询
     *
     * @param id
     * @return
     */
    @Override
    public User findById(Long id) {
        return userMapper.selectByPrimaryKey(id);
    }

    /**
     * 新增
     *
     * @param user
     */
    @Override
    public void add(User user) {
        userMapper.insert(user);
    }

    /**
     * 修改
     *
     * @param user
     */
    @Override
    public void update(User user) {
        userMapper.updateByPrimaryKeySelective(user);
    }

    /**
     * 删除
     *
     * @param id
     */
    @Override
    public void delete(Long id) {
        userMapper.deleteByPrimaryKey(id);
    }

    /**
     * 构建查询条件
     *
     * @param searchMap
     * @return
     */
    private Example createExample(Map<String, Object> searchMap) {
        Example example = new Example(User.class);
        Example.Criteria criteria = example.createCriteria();
        if (searchMap != null) {
            // password
            if (searchMap.get("password") != null && !"".equals(searchMap.get("password"))) {
                criteria.andLike("password", "%" + searchMap.get("password") + "%");
            }
            // phone
            if (searchMap.get("phone") != null && !"".equals(searchMap.get("phone"))) {
                criteria.andLike("phone", "%" + searchMap.get("phone") + "%");
            }
            // refresh_token
            if (searchMap.get("refreshToken") != null && !"".equals(searchMap.get("refreshToken"))) {
                criteria.andLike("refreshToken", "%" + searchMap.get("refreshToken") + "%");
            }
            // salt
            if (searchMap.get("salt") != null && !"".equals(searchMap.get("salt"))) {
                criteria.andLike("salt", "%" + searchMap.get("salt") + "%");
            }
            // token
            if (searchMap.get("token") != null && !"".equals(searchMap.get("token"))) {
                criteria.andLike("token", "%" + searchMap.get("token") + "%");
            }
            // username
            if (searchMap.get("username") != null && !"".equals(searchMap.get("username"))) {
                criteria.andLike("username", "%" + searchMap.get("username") + "%");
            }

            // login_type
            if (searchMap.get("loginType") != null) {
                criteria.andEqualTo("loginType", searchMap.get("loginType"));
            }
            // status
            if (searchMap.get("status") != null) {
                criteria.andEqualTo("status", searchMap.get("status"));
            }

        }
        return example;
    }

}
